#ifndef __EASYC_H__
#define __EASYC_H__

#include <windows.h>
#include <tchar.h>

#ifndef WINVER
#define WINVER 0x0400			// Specifies that the minimum required platform is Windows 95 and Windows NT 4.0.
#endif

#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0500		// Specifies that the minimum required platform is Windows 2000
#endif

#ifndef _WIN32_WINDOWS
#define _WIN32_WINDOWS 0x0410	// Specifies that the minimum required platform is Windows 98
#endif

// EasyX Window Properties
#define EX_SHOWCONSOLE		1		// Maintain the console window when creating a graphics window
#define EX_NOCLOSE			2		// Disable the close button
#define EX_NOMINIMIZE		4		// Disable the minimize button
#define EX_DBLCLKS			8		// Support double-click events

// Color constant
#define	BLACK			0
#define	BLUE			0xAA0000
#define	GREEN			0x00AA00
#define	CYAN			0xAAAA00
#define	RED				0x0000AA
#define	MAGENTA			0xAA00AA
#define	BROWN			0x0055AA
#define	LIGHTGRAY		0xAAAAAA
#define	DARKGRAY		0x555555
#define	LIGHTBLUE		0xFF5555
#define	LIGHTGREEN		0x55FF55
#define	LIGHTCYAN		0xFFFF55
#define	LIGHTRED		0x5555FF
#define	LIGHTMAGENTA	0xFF55FF
#define	YELLOW			0x55FFFF
#define	WHITE			0xFFFFFF

#ifndef __cplusplus
typedef char bool;		// Define bool type for C
#endif

#ifdef __cplusplus
extern "C" {
#endif

// Graphics window related functions
HWND graphCreate(int width, int height);
HWND graphInit(int width, int height, int flag);
void graphClose();
void graphClear();
void graphReset();				// Reset the graphics environment as default
int  graphGetWidth();			// Get the width of current graphics device
int  graphGetHeight();			// Get the height of current graphics device
HWND graphGetHWnd();					// Get the handle of the graphics window

// Graphics environment related functions
void cliprgnSet(HRGN hrgn);				// Set clip region
void cliprgnClear();					// Clear clip region


typedef void* __LINESTYLE;

__LINESTYLE lineStyleInit();
__LINESTYLE lineStyleCopy(__LINESTYLE style);
void        lineStyleFree(__LINESTYLE style);


typedef void* __FILLSTYLE;

__FILLSTYLE fillStyleInit();
__FILLSTYLE fillStyleCopy(__FILLSTYLE style);
void        fillStyleFree(__FILLSTYLE style);


typedef void* __IMAGE;
__IMAGE imageInit(int width, int height);
__IMAGE imageCopy(__IMAGE img);
void    imageFree(__IMAGE img);
void    imageResize(__IMAGE img, int width, int height);
int     imageGetWidth(__IMAGE img);
int     imageGetHeight(__IMAGE img);


void originSet(int x, int y);				// Set coordinate origin
void aspectratioGet(float *pxasp, float *pyasp);	// Get aspect ratio
void aspectratioSet(float xasp, float yasp);	// Set aspect ratio


int  rop2Get();					// Get binary raster operation mode
void rop2Set(int mode);			// Set binary raster operation mode
int  polyfillModeGet();			// Get polygon fill mode
void polyfillModeSet(int mode);	// Set polygon fill mode


COLORREF lineColorGet();			// Get line color
void     lineColorSet(COLORREF color);
COLORREF textColorGet();			// Get text color
void     textColorSet(COLORREF color);
COLORREF fillColorGet();
void     fillColorSet(COLORREF color);
COLORREF bkColorGet();				// Get background color
void     bkColorSet(COLORREF color);
int      bkModeGet();				// Get background mode
void     bkModeSet(int mode);		// Set background mode


COLORREF RGB2GRAY(COLORREF rgb);	// Convert RGB to grayscale
void     RGB2HSL(COLORREF rgb, float *H, float *S, float *L);	// Convert RGB to HSL
void     RGB2HSV(COLORREF rgb, float *H, float *S, float *V);	// Convert RGB to HSV
COLORREF HSL2RGB(float H, float S, float L);	// Convert HSL to RGB
COLORREF HSV2RGB(float H, float S, float V);	// Convert HSV to RGB


COLORREF getPixel(int x, int y);				// Get pixel color
void     putPixel(int x, int y, COLORREF color);	// Set pixel color


void lineDraw(int x1, int y1, int x2, int y2);	// Draw a line


void rectangleDraw(int left, int top, int right, int bottom);	// Draw a rectangle without filling
void rectangleFill(int left, int top, int right, int bottom);	// Draw a filled rectangle with a border
void rectangleSolid(int left, int top, int right, int bottom);	// Draw a filled rectangle without a border
void rectangleClear(int left, int top, int right, int bottom);


void circleDraw(int x, int y, int radius);		// Draw a circle without filling
void circleFill(int x, int y, int radius);
void circleSolid(int x, int y, int radius);		// Draw a filled circle without a border
void circleClear(int x, int y, int radius);		// Clear a circular region


void ellipseDraw(int left, int top, int right, int bottom);	// Draw an ellipse without filling
void ellipseFill(int left, int top, int right, int bottom);
void ellipseSolid(int left, int top, int right, int bottom);	// Draw a filled ellipse without a border
void ellipseClear(int left, int top, int right, int bottom);	// Clear an elliptical region


void roundRectDraw(int left, int top, int right, int bottom, int ellipseWidth, int ellipseHeight);	// Draw a rounded rectangle without filling
void roundRectFill(int left, int top, int right, int bottom, int ellipseWidth, int ellipseHeight);	// Draw a filled rounded rectangle with a border
void roundRectSolid(int left, int top, int right, int bottom, int ellipseWidth, int ellipseHeight);
void roundRectClear(int left, int top, int right, int bottom, int ellipseWidth, int ellipseHeight);	// Clear a rounded rectangular region


void pieArc(int left, int top, int right, int bottom, double stangle, double endangle);	// Draw a sector without filling
void pieDraw(int left, int top, int right, int bottom, double stangle, double endangle);	// Draw a pie without filling
void pieFill(int left, int top, int right, int bottom, double stangle, double endangle);	// Draw a filled sector with a border
void pieSolid(int left, int top, int right, int bottom, double stangle, double endangle);	// Draw a filled sector without a border
void pieClear(int left, int top, int right, int bottom, double stangle, double endangle);	// Clear a rounded rectangular region


void polyLineDraw(const POINT *points, int num);								// Draw a polygon without filling
void polygonDraw(const POINT *points, int num);								// Draw a polygon without filling
void polygonFill(const POINT *points, int num);
void polygonSolid(const POINT *points, int num);								// Draw a filled polygon without a border
void polygonClear(const POINT *points, int num);								// Clear a polygon region


void bezierDraw(const POINT *points, int num);								// Draw a Bezier curve


void floodFill(int x, int y, COLORREF color, int filltype);	// Fill the area


void strPut(int x, int y, char *str);
int  strDraw(char* str, RECT* pRect, UINT uFormat);
int  strWidth(char *str);
int  strHeight(char *str);

void charPut(int x, int y, char c);
int  charDraw(char c, RECT* pRect, UINT uFormat);
int  charWidth(char c);
int  charHeight(char c);


void imageLoad(__IMAGE pDstImg, char* pImgFile);	// Load image from file
void imageCarry(__IMAGE pDstImg, char* pImgFile, int nWidth, int nHeight, bool bResize);	// Load image from file with resizing
void imageSave(char* pImgFile, __IMAGE pImg);	// Save image to file
void imageGet(__IMAGE pDstImg, int srcX, int srcY, int srcWidth, int srcHeight);	// Get image from device
void imagePut(int dstX, int dstY, const __IMAGE pSrcImg, DWORD dwRop);
void imageDraw(int dstX, int dstY, int dstWidth, int dstHeight, const __IMAGE pSrcImg, int srcX, int srcY, DWORD dwRop);	// Put image to device
void imageRotate(__IMAGE dstimg, __IMAGE srcimg, double radian);	// Rotate image
void imagePivot(__IMAGE dstimg, __IMAGE srcimg, double radian, COLORREF bkcolor, bool autosize, bool highquality);	// Rotate image with pivot point

DWORD*  imageGetBuffer(__IMAGE pImg);	// Get the display buffer of the graphics device
__IMAGE imageGetWorking();		// Get current graphics device
void    imageSetWorking(__IMAGE pImg);	// Set current graphics device
HDC     imageGetHDC(__IMAGE pImg);	// Get the graphics device handle


void batchDrawBegin();		// Begin batch drawing mode
void batchDrawFlush();
void batchDrawEnd();		// End batch drawing mode and refreshes the undisplayed drawing


const char* getEasyXVersion();	// Get version of EasyX library


#define EX_MOUSE	1
#define EX_KEY		2
#define EX_CHAR		4
#define EX_WINDOW	8

struct __ExMsg{
    unsigned short message;					// The message identifier
    union {
        // Data of the mouse message
        struct {
            bool ctrl : 1;		// Indicates whether the CTRL key is pressed
            bool shift : 1;		// Indicates whether the SHIFT key is pressed
            bool lbutton : 1;		// Indicates whether the left mouse button is pressed
            bool mbutton : 1;		// Indicates whether the middle mouse button is pressed
            bool rbutton : 1;		// Indicates whether the right mouse button is pressed
            short x;				// The x-coordinate of the cursor
            short y;				// The y-coordinate of the cursor
            short wheel;			// The distance the wheel is rotated, expressed in multiples or divisions of 120
        };

        // Data of the key message
        struct {
            BYTE vkcode;			// The virtual-key code of the key
            BYTE scancode;			// The scan code of the key. The value depends on the OEM
            bool extended : 1;		// Indicates whether the key is an extended key, such as a function key or a key on the numeric keypad. The value is true if the key is an extended key; otherwise, it is false.
            bool prevdown : 1;		// Indicates whether the key is previously up or down
        };

        // Data of the char message
        TCHAR ch;

        // Data of the window message
        struct {
            WPARAM wParam;
            LPARAM lParam;
        };
    };
};
typedef struct __ExMsg ExMsg;

ExMsg messageGet();
ExMsg messageFilter(BYTE filter);
void  messageSave(ExMsg *msg);
void  messageSelect(ExMsg *msg, BYTE filter);
bool  messagePeek(ExMsg *msg, BYTE filter);
void  messageFlush(BYTE filter);
void  messageClear();


#ifdef __cplusplus
}
#endif


#endif//__EASYC_H__